<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<title>Looping Over Scope</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
		<meta name="viewport" content="width=device-width initial-scale=1">
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<meta http-equiv="Content-Language" content="en-gb">

<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
function togglePopup(material_id) {
  var popup = document.getElementById(material_id);
  popup.classList.toggle("show");
}
</script>

<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
		
	</head>
	<body class="commentary-font">
		<nav role="navigation">
		<h1><a href="../index.html"><img src="../docs-assets/Inform.png" height=72> </a></h1>
<ul><li><a href="../index.html">home</a></li>
</ul><h2>Compiler</h2><ul>
<li><a href="../structure.html">structure</a></li>
<li><a href="../inbuildn.html">inbuild</a></li>
<li><a href="../inform7n.html">inform7</a></li>
<li><a href="../intern.html">inter</a></li>
<li><a href="../services.html">services</a></li>
<li><a href="../secrets.html">secrets</a></li>
</ul><h2>Other Tools</h2><ul>
<li><a href="../inblorbn.html">inblorb</a></li>
<li><a href="../inform6.html">inform6</a></li>
<li><a href="../inpolicyn.html">inpolicy</a></li>
</ul><h2>Resources</h2><ul>
<li><a href="../extensions.html">extensions</a></li>
<li><a href="../kits.html">kits</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=0> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="https://github.com/ganelson/inweb"><img src="../docs-assets/github.png" height=0> inweb</a></li>
<li><a href="https://github.com/ganelson/intest"><img src="../docs-assets/github.png" height=0> intest</a></li>
</ul>
		</nav>
		<main role="main">
		<!-- Weave of 'Looping Over Scope' generated by inweb -->
<div class="breadcrumbs">
    <ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../inform7n.html">Inform7</a></li><li><a href="index.html">runtime</a></li><li><a href="index.html#4">Chapter 4: Enclosed Resources</a></li><li><b>Looping Over Scope</b></li></ul></div>
<p class="purpose">To compile functions which implement conditions such as "in the presence of Mrs Dalloway".</p>

<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. </b>Each time we need to parse an action pattern with the provison "in the
presence of X", one of the following objects is created, as an instruction
to pass to the agent below. These tests are local resources, included in
the same enclosure as the function they are called from. Each test is used
in just one place in the program.
</p>

<p class="commentary">The term "loop over scope" is traditional and goes back to the Inform 6
world model, where the "scope" was the set of things which the player could
interact with at any given point.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">loop_over_scope</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">what_to_find</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">inter_name</span><span class="plain-syntax"> *</span><span class="identifier-syntax">los_iname</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">loop_over_scope</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure loop_over_scope is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>Because the test is performed by a separate function, we need to make sure
that any called variables are created in the calling function, and not in
that external one: so we remove calling details from <span class="extract"><span class="extract-syntax">what_to_find</span></span>.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">loop_over_scope</span><span class="plain-syntax"> *</span><span class="function-syntax">LoopingOverScope::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">what</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">loop_over_scope</span><span class="plain-syntax"> *</span><span class="identifier-syntax">los</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">loop_over_scope</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">los</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">what_to_find</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::duplicate</span><span class="plain-syntax">(</span><span class="identifier-syntax">what</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Specifications::is_description</span><span class="plain-syntax">(</span><span class="identifier-syntax">what</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">los</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">what_to_find</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::duplicate</span><span class="plain-syntax">(</span><span class="identifier-syntax">los</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">what_to_find</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Descriptions::clear_calling</span><span class="plain-syntax">(</span><span class="identifier-syntax">los</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">what_to_find</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">los</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">los_iname</span><span class="plain-syntax"> = </span><a href="4-enc.html#SP1" class="function-link"><span class="function-syntax">Enclosures::new_iname</span></a><span class="plain-syntax">(</span><span class="constant-syntax">LOOPS_OVER_SCOPE_HAP</span><span class="plain-syntax">, </span><span class="constant-syntax">LOOP_OVER_SCOPE_FN_HL</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">desc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::new</span><span class="plain-syntax">();</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">desc</span><span class="plain-syntax">, </span><span class="string-syntax">"loop over scope '%W'"</span><span class="plain-syntax">, </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">los</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">what_to_find</span><span class="plain-syntax">));</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Sequence::queue</span><span class="plain-syntax">(&amp;</span><a href="4-los.html#SP3" class="function-link"><span class="function-syntax">LoopingOverScope::compilation_agent</span></a><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">STORE_POINTER_loop_over_scope</span><span class="plain-syntax">(</span><span class="identifier-syntax">los</span><span class="plain-syntax">), </span><span class="identifier-syntax">desc</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">los</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. </b>And here we compile a single test.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">LoopingOverScope::compilation_agent</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">LoopingOverScope::compilation_agent</span></span>:<br/><a href="4-los.html#SP2">&#167;2</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">compilation_subtask</span><span class="plain-syntax"> *</span><span class="identifier-syntax">t</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">loop_over_scope</span><span class="plain-syntax"> *</span><span class="identifier-syntax">los</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RETRIEVE_POINTER_loop_over_scope</span><span class="plain-syntax">(</span><span class="identifier-syntax">t</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">data</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">packaging_state</span><span class="plain-syntax"> </span><span class="identifier-syntax">save</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Functions::begin</span><span class="plain-syntax">(</span><span class="identifier-syntax">los</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">los_iname</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">stack_frame</span><span class="plain-syntax"> *</span><span class="identifier-syntax">phsf</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Frames::current_stack_frame</span><span class="plain-syntax">();</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">it_lv</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Frames::enable_it</span><span class="plain-syntax">(</span><span class="identifier-syntax">phsf</span><span class="plain-syntax">, </span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">it_s</span><span class="plain-syntax"> = </span><span class="identifier-syntax">LocalVariables::declare</span><span class="plain-syntax">(</span><span class="identifier-syntax">it_lv</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><a href="2-ec.html#SP14" class="function-link"><span class="function-syntax">EmitCode::inv</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">IF_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-ec.html#SP3" class="function-link"><span class="function-syntax">EmitCode::down</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">CompileConditions::begin</span><span class="plain-syntax">();</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">los</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">what_to_find</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lv_sp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Lvalues::new_LOCAL_VARIABLE</span><span class="plain-syntax">(</span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">, </span><span class="identifier-syntax">it_lv</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">RTActionPatterns::value_matches_specification</span><span class="plain-syntax">(</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">lv_sp</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">los</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">what_to_find</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        } </span><span class="reserved-syntax">else</span>
<span class="plain-syntax">            </span><a href="2-ec.html#SP8" class="function-link"><span class="function-syntax">EmitCode::val_false</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">CompileConditions::end</span><span class="plain-syntax">();</span>
<span class="plain-syntax">        </span><a href="2-ec.html#SP5" class="function-link"><span class="function-syntax">EmitCode::code</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax">        </span><a href="2-ec.html#SP3" class="function-link"><span class="function-syntax">EmitCode::down</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax">            </span><a href="2-ec.html#SP14" class="function-link"><span class="function-syntax">EmitCode::inv</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><a href="2-ec.html#SP3" class="function-link"><span class="function-syntax">EmitCode::down</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax">                </span><a href="2-ec.html#SP13" class="function-link"><span class="function-syntax">EmitCode::ref_iname</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><a href="2-hrr.html#SP11" class="function-link"><span class="function-syntax">Hierarchy::find</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">LOS_RV_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax">                </span><a href="2-ec.html#SP8" class="function-link"><span class="function-syntax">EmitCode::val_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">it_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><a href="2-ec.html#SP3" class="function-link"><span class="function-syntax">EmitCode::up</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax">        </span><a href="2-ec.html#SP3" class="function-link"><span class="function-syntax">EmitCode::up</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax">    </span><a href="2-ec.html#SP3" class="function-link"><span class="function-syntax">EmitCode::up</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Functions::end</span><span class="plain-syntax">(</span><span class="identifier-syntax">save</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">
    <ul class="progressbar"><li class="progressprev"><a href="4-gt.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-rm.html">1</a></li><li class="progresschapter"><a href="2-hrr.html">2</a></li><li class="progresschapter"><a href="3-gm.html">3</a></li><li class="progresscurrentchapter">4</li><li class="progresssection"><a href="4-enc.html">enc</a></li><li class="progresssection"><a href="4-ll.html">ll</a></li><li class="progresssection"><a href="4-tl.html">tl</a></li><li class="progresssection"><a href="4-ts.html">ts</a></li><li class="progresssection"><a href="4-rsp.html">rsp</a></li><li class="progresssection"><a href="4-bq.html">bq</a></li><li class="progresssection"><a href="4-rl.html">rl</a></li><li class="progresssection"><a href="4-sal.html">sal</a></li><li class="progresssection"><a href="4-vnl.html">vnl</a></li><li class="progresssection"><a href="4-gt.html">gt</a></li><li class="progresscurrent">los</li><li class="progresschapter"><a href="5-act.html">5</a></li><li class="progresschapter"><a href="6-bd.html">6</a></li><li class="progresschapter"><a href="7-cg.html">7</a></li><li class="progressnext"><a href="5-act.html">&#10095;</a></li></ul></div>
</nav><!-- End of weave -->

		</main>
	</body>
</html>

